package com.palmshop.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONObject;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.POIXMLTextExtractor;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.springframework.web.multipart.MultipartFile;

/**
 * 工具类
 * @author quan
 *
 */
public class Qutil {

	private static int a = 10000;

	/**
	 * 
	 * @Title: processFileName
	 * 
	 * @Description: ie,chrom,firfox下处理文件名显示乱码
	 */
	public static String processFileName(HttpServletRequest request,
			String fileNames) {
		String codedfilename = null;
		try {
			String agent = request.getHeader("USER-AGENT");
			if (null != agent && -1 != agent.indexOf("MSIE") || null != agent
					&& -1 != agent.indexOf("Trident")) {// ie

				String name = java.net.URLEncoder.encode(fileNames, "UTF8");

				codedfilename = name;
			} else if (null != agent && -1 != agent.indexOf("Mozilla")) {// 火狐,chrome等

				codedfilename = new String(fileNames.getBytes("UTF-8"),
						"iso-8859-1");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return codedfilename;
	}

	/**
	 * 当前日期上加一天返回
	 * 
	 * @param dateStr
	 * @return
	 * @throws ParseException
	 */
	public static String getAddDateT(String dateStr) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Calendar cal = Calendar.getInstance();
		cal.setTime(sdf.parse(dateStr));
		cal.add(Calendar.DATE, 1);
		return sdf.format(cal.getTime());
	}

	/**
	 * 当前日期上加一天返回，不用calendar
	 * 
	 * @param dateStr
	 * @return
	 * @throws ParseException
	 */
	public static String getAddDate(String dateStr) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		return sdf.format(new Date(sdf.parse(dateStr).getTime() + 1000 * 60
				* 60 * 24));
	}

	/**
	 * 获取客户端的ip
	 * 
	 * @param request
	 * @return
	 */
	public static String getIp(HttpServletRequest request) {
		String ip = request.getHeader("X-Forwarded-For");
		if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
			// 多次反向代理后会有多个ip值，第一个ip才是真实ip
			int index = ip.indexOf(",");
			if (index != -1) {
				return ip.substring(0, index);
			} else {
				return ip;
			}
		}
		ip = request.getHeader("X-Real-IP");
		if (StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
			return ip;
		}
		return request.getRemoteAddr();
	}

	/**
	 * 返回一列数字号码 年月日秒加上0-80000的数字
	 * 
	 * @return
	 */
	public synchronized static String createNumT() {
		a++;
		if (a > 80000) {
			a = 10000;
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		return sdf.format(new Date()) + a;

	}

	/**
	 * 
	 * 当前毫秒数作为唯一性标识
	 * @return
	 */
	public synchronized static String createNum() {
		
		return String.valueOf(System.currentTimeMillis());

	}
	
	
	/**
	 * 返回一列数字号码 年月日秒加上0-80000的数字
	 * 
	 * @return
	 */
	public synchronized static String createNumB() {
		a++;
		if (a > 80000) {
			a = 10000;
		}
		SimpleDateFormat sdf = new SimpleDateFormat("MMddyyyyHHmmss");
		return sdf.format(new Date()) + a;

	}

	/**
	 * 返回一个当前时间的字符串 用于 生成时间的设置
	 * 
	 * @return
	 */
	public static String getTime() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return sdf.format(new Date());
	}

	/**
	 * 返回一个当前时间的字符串 用于 生成时间的设置
	 * 
	 * @return
	 */
	public static String getTimeM() {
		return new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date());
	}

	/**
	 * 返回一个当天日期的字符串
	 * 
	 * @return
	 */
	public static String getDate() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		return sdf.format(new Date());
	}

	/**
	 * 产生一个UUID，去掉“-”后返回
	 * 
	 * @return
	 */
	public static String createId() {
		UUID uuid = UUID.randomUUID();
		String uu1 = uuid.toString();
		uu1 = uu1.replaceAll("-", "");
		return uu1;
	}

	public static String creteUUID() {
		return UUID.randomUUID().toString().replaceAll("-", "");
	}

	/**
	 * 使用md5将给定的字符串进行加密处理
	 * 
	 * @param msg
	 *            :要加密的字符串
	 * @return
	 * @throws Exception
	 */
	public static String md5(String msg) throws Exception {
		// MessageDigest md = MessageDigest.getInstance("MD5");// 利用md5对msg处理
		// byte[] input = msg.getBytes();
		// byte[] output = md.digest(input);// 将字节信息处理
		return Base64.encodeBase64String(MessageDigest.getInstance("MD5")
				.digest(msg.getBytes()));// 将md5处理的output结果转成字符串返回
	}

	/**
	 * 将json格式的字符串解析成Map对象 <li>
	 * json格式：{"name":"admin","retries":"3fff","testname"
	 * :"ddd","testretries":"fffffffff"}
	 */
	private static HashMap<String, Object> toHashMap(Object object) {
		HashMap<String, Object> data = new HashMap<String, Object>();
		JSONObject jsonObject = JSONObject.fromObject(object);// 将json字符串转换成jsonObject
		Iterator it = jsonObject.keys();
		while (it.hasNext()) {// 遍历jsonObject数据，添加到Map对象
			String key = String.valueOf(it.next());
			String value = (String) jsonObject.get(key);
			data.put(key, value);
		}
		return data;
	}

	/**
	 * 实现表单文件的上传功能;文件名固定
	 * 
	 * @param fileName
	 *            :form表中的文件
	 * @param request
	 * @param path
	 *            ：传递过来文件要保存的路径
	 * @param picName
	 *            ：传递过来文件要保存的名字
	 * @return
	 * @throws Exception
	 */
	public static File handleFileUpId(MultipartFile fileName,
			HttpServletRequest request, String path, String picName)
			throws Exception {
		File file = null;
		File fileDir = new File(path);// 此目录是根据保单id创建的，每个id对应一个目录
		if (fileDir.isDirectory()) {
			File[] subs = fileDir.listFiles();// 获取目录下的子文件
			for (File sub : subs) {// 遍历每一个文件
				if (picName != null
						&& picName.equals(sub.getName().substring(0,
								sub.getName().lastIndexOf(".")))) {// 只根据文件的名字进行匹配
					sub.delete();// 如果有重名的文件则执行覆盖操作
				}
			}
		}
		if (!fileName.isEmpty()) {
			String name = picName
					+ fileName.getOriginalFilename().substring(
							fileName.getOriginalFilename().lastIndexOf("."));// 设置文件名
			file = new File(path + File.separator + name);
			if (file.exists()) {// 前面已经过滤；暂时保留
				file.delete();
			}
			file.createNewFile();// 创建生成文件

			fileName.transferTo(file);// 将fileName转成file

		}

		return file;
	}

	// 递归删除指定路径下的所有文件
	public static void deleteAll(File file) {
		if (file.isFile() || file.list().length == 0) {
			file.delete();
		} else {
			File[] files = file.listFiles();
			for (File f : files) {
				deleteAll(f);// 递归删除每一个文件
				f.delete();// 删除该文件夹
			}
		}
	}

	/**
	 * 实现表单文件的上传功能 弃用保留
	 * 
	 * @param fileName
	 *            :form表中的文件
	 * @param request
	 * @param path
	 *            ：传递过来文件要保存的路径
	 * @return
	 * @throws Exception
	 */
	public static File handleFileUp(MultipartFile fileName,
			HttpServletRequest request, String path) throws Exception {
		File file = null;
		if (!fileName.isEmpty()) {
			String name = UUID.randomUUID().toString().replaceAll("-", "")
					+ fileName.getOriginalFilename()
							.substring(
									fileName.getOriginalFilename().lastIndexOf(
											"\\.") + 1);// 生成一个唯一的文件名

			file = new File(path + File.separator + name);
			if (!file.exists()) {
				file.createNewFile();// 事实上肯定是需要创建生成的
			}
			fileName.transferTo(file);// 将fileName转成file

		}

		return file;
	}

	/**
	 * 导出excel表格
	 * 
	 * @param header
	 *            表头
	 * @param lists
	 *            数据列
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static <T> HSSFWorkbook exportExcel(String[] header, List<T> lists,
			String[] removeKey) {
		HSSFWorkbook wb = new HSSFWorkbook();// 创建一个新的excel
		HSSFSheet sheet = wb.createSheet("sheet1");// 创建sheet页
		sheet.setDefaultColumnWidth(16);// 设定excel每一列的宽度

		HSSFRow row = sheet.createRow(0);// 创建一行用来写入标题
		HSSFCellStyle cStyle = wb.createCellStyle();// 创建一个样式
		cStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 设置居中样式
		for (int i = 0; i < header.length; i++) {
			HSSFCell cell = row.createCell(i);
			cell.setCellValue(header[i]);
			cell.setCellStyle(cStyle);
		}
		String[] keys = null;
		if (!lists.isEmpty()) {
			Map<String, Object> map = (Map<String, Object>) lists.get(0);// 过滤掉不需要显示的字段
			if (removeKey.length > 0) {
				for (String key : removeKey) {
					map.remove(key);
				}
			}
			keys = new String[map.keySet().size()];
			int index = 0;
			for (String key : ((Map<String, Object>) (lists.get(0))).keySet()) { // 生成头部列表，
				keys[index] = key;
				index++;
			}
			for (int i = 0; i < lists.size(); i++) {
				row = sheet.createRow(i + 1);
				T t = lists.get(i);
				if (t instanceof Map && t != null) {
					for (int j = 0; j < header.length; j++) {
						Cell cell = row.createCell(j);
						cell.setCellType(cell.CELL_TYPE_STRING);
						cell.setCellValue((((Map) t).get(keys[j]) == null) ? ""
								: String.valueOf(((Map) t).get(keys[j])));
					}
				}
			}

			// for (int col = 0; col <map.keySet().size() ; col++) {
			// // 根据内容自动调整列宽;对性能有影响
			// sheet.autoSizeColumn(col, true);
			// }

		}
		return wb;
	}

	/**
	 * 主要用户实现文件的压缩功能
	 * 
	 * @param srcfile
	 *            :要压缩的源文件数组
	 * @param zipfile
	 *            ：压缩后的目标文件
	 */
	public static void ZipFiles(File[] srcfile, File zipfile) {

		byte[] buf = new byte[1024];
		try {
			ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
					zipfile));
			for (int i = 0; i < srcfile.length; i++) {
				FileInputStream in = new FileInputStream(srcfile[i]);
				out.putNextEntry(new ZipEntry(srcfile[i].getName()));
				int len;
				while ((len = in.read(buf)) > 0) {
					out.write(buf, 0, len);
				}
				out.closeEntry();
				in.close();
			}
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * poi读取excel内容;保留 保险理赔批量修改使用
	 * 
	 * @param fileName
	 *            :需要读取的excel文件名；默认xls格式；测试xlsx也没问题！！
	 */
	public static String readExcel(String fileName) {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();// 创建一个list用来存储读取的内容
		StringBuffer sb = new StringBuffer("");// 用字符串的方式存储读取的内容
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			InputStream is = new FileInputStream(fileName);// 创建一个输入流读取excel内容
			HSSFWorkbook wbs = new HSSFWorkbook(is); // 获取excel
			HSSFSheet childSheet = wbs.getSheetAt(0);// 获取第一个sheet表格
			// System.out.println("有行数" + (childSheet.getLastRowNum()+1));
			for (int j = 0; j < childSheet.getLastRowNum() + 1; j++) {// 循环读取每一行
																		// 的值
				HSSFRow row = childSheet.getRow(j); // 获取行
				if (null != row) {
					for (int k = 0; k < row.getLastCellNum(); k++) {// 循环读取每一列的值
						HSSFCell cell = row.getCell(k);// 获取单元格
						if (null != cell) {
							switch (cell.getCellType()) {
							case HSSFCell.CELL_TYPE_NUMERIC: // 数字
								if (HSSFDateUtil.isCellDateFormatted(cell)) {
									// 如果是date类型则 ，获取该cell的date值
									// list.add(HSSFDateUtil.getJavaDate(cell.getNumericCellValue()).toString()+
									// "   ");
									map.put(k + "",
											HSSFDateUtil.getJavaDate(
													cell.getNumericCellValue())
													.toString());
									// list.add(cell.getNumericCellValue()+
									// "   ");
								} else { // 纯数字
									// list.add(String.valueOf(cell.getNumericCellValue())+
									// "   ");

									map.put("state", String.valueOf(cell
											.getNumericCellValue()));
								}
								// list.add(cell.getNumericCellValue()+ "   ");
								break;
							case HSSFCell.CELL_TYPE_STRING: // 字符串；按规定上传的话都是字符串或者数字
								// list.add(cell.getStringCellValue()+ "   ");
								map.put("imei", cell.getStringCellValue());
								break;
							case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
								// list.add(cell.getBooleanCellValue()+ "   ");
								map.put(k + "", cell.getBooleanCellValue());
								break;
							case HSSFCell.CELL_TYPE_FORMULA: // 公式
								// list.add(cell.getCellFormula()+ "   ");
								map.put(k + "", cell.getCellFormula());
								break;
							case HSSFCell.CELL_TYPE_BLANK: // 空值
								// list.add(" ");
								map.put(k + "", " ");
								break;
							case HSSFCell.CELL_TYPE_ERROR: // 故障
								// list.add(" ");
								map.put(k + "", " ");
								break;
							default:
								// list.add("未知类型   ");
								map.put(k + "", "未知类型   ");
								break;
							}
						} else {
							// list.add("   ");
							map.put(k + "", "   ");
						}
					}
				}
				// list.add("\n");//换行
				list.add(map);
				System.out.println(map);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sb.toString();
	}

	/**
	 * poi读取excel内容；区分2003和2007版本
	 * 
	 * @param fileName
	 *            :需要读取的excel文件名；xls格式正常；xlsx格式Package should contain a content
	 *            type part [M1.13]
	 */
	public static void readXml(String fileName) {
		boolean isE2007 = false; // 判断是否是excel2007格式
		if (fileName.endsWith("xlsx")) {
			isE2007 = true;
		}
		try {
			InputStream input = new FileInputStream(fileName); // 建立输入流
			Workbook wb = null;
			// 根据文件格式(2003或者2007)来初始化
			if (isE2007) {
				wb = new XSSFWorkbook(input);
			} else {
				wb = new HSSFWorkbook(input);
			}
			Sheet sheet = wb.getSheetAt(0); // 获得第一个表单
			Iterator<Row> rows = sheet.rowIterator(); // 获得第一个表单的迭代器
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 读取word内容
	 */
	public static void readWord(String fileName) {
		try {
			// word 2003： 图片不会被读取
			// InputStream is = new FileInputStream(new
			// File("c://files//2003.doc"));
			// WordExtractor ex = new WordExtractor(is);
			// String text2003 = ex.getText();
			// System.out.println(text2003);

			// word 2007 图片不会被读取， 表格中的数据会被放在字符串的最后
			OPCPackage opcPackage = POIXMLDocument.openPackage(fileName);
			POIXMLTextExtractor extractor = new XWPFWordExtractor(opcPackage);
			String text2007 = extractor.getText();
			System.out.println(text2007);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 用于产生随机的定长的字符串
	 * 
	 * @param numberFlag
	 *            :是否是数字
	 * @param length
	 *            :长度
	 * @return
	 */
	public static String createRandom(boolean numberFlag, int length) {
		String retStr = "";
		String strTable = numberFlag ? "1234567890"
				: "1234567890abcdefghijkmnpqrstuvwxyz";
		int len = strTable.length();
		boolean bDone = true;
		do {
			retStr = "";
			int count = 0;
			for (int i = 0; i < length; i++) {
				double dblR = Math.random() * len;
				int intR = (int) Math.floor(dblR);
				char c = strTable.charAt(intR);
				if (('0' <= c) && (c <= '9')) {
					count++;
				}
				retStr += strTable.charAt(intR);
			}
			if (count >= 2) {
				bDone = false;
			}
		} while (bDone);
		return retStr;
	}

	/**
	 * 用来测试工具方法
	 * 
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		// readExcel("D:"+File.separator+"toubao20160416.xls");
		System.out.println(getTimeM());
		System.out.println("sfsfsdfs");

	}
}
